home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / FPU-EMU / FPU_AUX.C < prev    next >
C/C++ Source or Header  |  1994-05-27  |  4KB  |  186 lines

  1. /*---------------------------------------------------------------------------+
  2.  |  fpu_aux.c                                                                |
  3.  |                                                                           |
  4.  | Code to implement some of the FPU auxiliary instructions.                 |
  5.  |                                                                           |
  6.  | Copyright (C) 1992,1993,1994                                              |
  7.  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  8.  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
  9.  |                                                                           |
  10.  |                                                                           |
  11.  +---------------------------------------------------------------------------*/
  12.  
  13. #include "fpu_system.h"
  14. #include "exception.h"
  15. #include "fpu_emu.h"
  16. #include "status_w.h"
  17. #include "control_w.h"
  18.  
  19.  
  20. static void fnop(void)
  21. {
  22. }
  23.  
  24. void fclex(void)
  25. {
  26.   partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
  27.            SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
  28.            SW_Invalid);
  29.   NO_NET_DATA_EFFECT;
  30.   FPU_entry_eip = ip_offset;               /* We want no net effect */
  31. }
  32.  
  33. /* Needs to be externally visible */
  34. void finit()
  35. {
  36.   int r;
  37.   control_word = 0x037f;
  38.   partial_status = 0;
  39.   top = 0;            /* We don't keep top in the status word internally. */
  40.   for (r = 0; r < 8; r++)
  41.     {
  42.       regs[r].tag = TW_Empty;
  43.     }
  44.   /* The behaviour is different to that detailed in
  45.      Section 15.1.6 of the Intel manual */
  46.   data_operand_offset = 0;
  47.   operand_selector = 0;
  48.   NO_NET_DATA_EFFECT;
  49.   FPU_entry_op_cs = 0;
  50.   FPU_entry_eip = ip_offset = 0;
  51. }
  52.  
  53. /*
  54.  * These are nops on the i387..
  55.  */
  56. #define feni fnop
  57. #define fdisi fnop
  58. #define fsetpm fnop
  59.  
  60. static FUNC const finit_table[] = {
  61.   feni, fdisi, fclex, finit,
  62.   fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
  63. };
  64.  
  65. void finit_()
  66. {
  67.   (finit_table[FPU_rm])();
  68. }
  69.  
  70.  
  71. static void fstsw_ax(void)
  72. {
  73.   *(short *) &FPU_EAX = status_word();
  74.   NO_NET_INSTR_EFFECT;
  75. }
  76.  
  77. static FUNC const fstsw_table[] = {
  78.   fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
  79.   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
  80. };
  81.  
  82. void fstsw_()
  83. {
  84.   (fstsw_table[FPU_rm])();
  85. }
  86.  
  87.  
  88. static FUNC const fp_nop_table[] = {
  89.   fnop, FPU_illegal, FPU_illegal, FPU_illegal,
  90.   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
  91. };
  92.  
  93. void fp_nop()
  94. {
  95.   (fp_nop_table[FPU_rm])();
  96. }
  97.  
  98.  
  99. void fld_i_()
  100. {
  101.   FPU_REG *st_new_ptr;
  102.  
  103.   if ( STACK_OVERFLOW )
  104.     { stack_overflow(); return; }
  105.  
  106.   /* fld st(i) */
  107.   if ( NOT_EMPTY(FPU_rm) )
  108.     { reg_move(&st(FPU_rm), st_new_ptr); push(); }
  109.   else
  110.     {
  111.       if ( control_word & EX_Invalid )
  112.     {
  113.       /* The masked response */
  114.       push();
  115.       stack_underflow();
  116.     }
  117.       else
  118.     EXCEPTION(EX_StackUnder);
  119.     }
  120.  
  121. }
  122.  
  123.  
  124. void fxch_i()
  125. {
  126.   /* fxch st(i) */
  127.   FPU_REG t;
  128.   register FPU_REG *sti_ptr = &st(FPU_rm);
  129.  
  130.   if ( FPU_st0_tag == TW_Empty )
  131.     {
  132.       if ( sti_ptr->tag == TW_Empty )
  133.     {
  134.       stack_underflow();
  135.       stack_underflow_i(FPU_rm);
  136.       return;
  137.     }
  138.       if ( control_word & CW_Invalid )
  139.     reg_move(sti_ptr, FPU_st0_ptr);   /* Masked response */
  140.       stack_underflow_i(FPU_rm);
  141.       return;
  142.     }
  143.   if ( sti_ptr->tag == TW_Empty )
  144.     {
  145.       if ( control_word & CW_Invalid )
  146.     reg_move(FPU_st0_ptr, sti_ptr);   /* Masked response */
  147.       stack_underflow();
  148.       return;
  149.     }
  150.   clear_C1();
  151.   reg_move(FPU_st0_ptr, &t);
  152.   reg_move(sti_ptr, FPU_st0_ptr);
  153.   reg_move(&t, sti_ptr);
  154. }
  155.  
  156.  
  157. void ffree_()
  158. {
  159.   /* ffree st(i) */
  160.   st(FPU_rm).tag = TW_Empty;
  161. }
  162.  
  163.  
  164. void ffreep()
  165. {
  166.   /* ffree st(i) + pop - unofficial code */
  167.   st(FPU_rm).tag = TW_Empty;
  168.   pop();
  169. }
  170.  
  171.  
  172. void fst_i_()
  173. {
  174.   /* fst st(i) */
  175.   reg_move(FPU_st0_ptr, &st(FPU_rm));
  176. }
  177.  
  178.  
  179. void fstp_i()
  180. {
  181.   /* fstp st(i) */
  182.   reg_move(FPU_st0_ptr, &st(FPU_rm));
  183.   pop();
  184. }
  185.  
  186.